import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_kit_plus/flutter_kit.dart';
import 'package:provider/provider.dart';

import '../class/notifier.dart';
import '../commont/upload_animation.dart';
import '../http/http.dart';
import '../tool/assets.dart';
import '../tool/tool.dart';

class UpdateView extends StatefulWidget {
  const UpdateView({super.key});

  @override
  State<UpdateView> createState() => _UpdateViewState();
}

class _UpdateViewState extends State<UpdateView> {
  Timer? _timer;
  final GlobalKey<GradientAnimationState> classBKey = GlobalKey<GradientAnimationState>();
  //late StreamSubscription<BluetoothConnectionState>? _subscription;

  ///工厂化
  Widget _item(BuildContext context, String title, String content) {
    return ListTile(
      title: Row(
        children: [
          Expanded(
            flex: 2, // 左边部分占固定宽度
            child: Text(
              title,
              style: const TextStyle(color: Colors.black),
            ),
          ),
          const SizedBox(width: 8),
          Expanded(
            flex: 3,
            child: Stack(
              alignment: Alignment.centerLeft,
              children: [
                const Positioned(
                  left: 0,
                  right: 0,
                  bottom: -4,
                  child: Divider(color: Colors.black, thickness: 1),
                ),
                Text(content, style: const TextStyle(color: Colors.red)),
              ],
            ),
          ),
        ],
      ),
      onTap: null,
      tileColor: Colors.white,
    );
  }

  ///工厂化
  Widget _item2(BuildContext context, bool enable) {
    final bluetoothSate = Provider.of<DeviceConnectStateNotifier>(context);

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const SizedBox(height: 150),
        Center(
          child: InkWell(
            onTap: enable == false
                ? null
                : () {
                    setState(() {
                      _requestOTA(context, bluetoothSate.connectedDevice!.platformName);
                      // read(context);
                    });
                  },
            child: Image.asset(
              enable ? assets.version_select : assets.version,
              height: 40,
            ),
          ),
        ),
      ],
    );
  }

  ///弹出窗口
  void _showDialog(BuildContext context) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return SimpleDialog(
          //insetPadding: EdgeInsets.all(300),
          backgroundColor: Colors.transparent,
          surfaceTintColor: Colors.transparent,
          children: [
            // Image.asset(assets.upload, height: 80),
            UploadAnimation(key: classBKey),
          ],
        );
      },
    );
  }

  ///方式1：服务器下载bin文件，进行ota
  Future<void> _requestOTA(BuildContext context, String ssid) async {
    EasyLoading.show(status: 'downloading...');

    String date = DateTime.now().toString();
    Map<String, dynamic>? response = await checkOTA(ssid);
    if (response == null) {
      EasyLoading.dismiss();
      return;
    }
    String result = '${date}:\n${jsonEncode(response)}';
    Provider.of<LogNotifier>(context, listen: false).newLog(result);

    String? url = response['data'];
    int code = response['code'];
    if (code == 200 && url != null && url!.length > 0) {
      Uint8List? bytes = await downloadFile(url, '${date}${ssid}.bin');
      EasyLoading.dismiss();
      _ota(bytes);
    } else {
      toast('code : ${code}\n error : ${response['msg']}');
    }
  }

  ///方式2；读取本地bin文件，进行ota
  Future<void> read(BuildContext context) async {
    // Uint8List? bytes = await assets.readBinFile('DSP88BTzheng.bin');
    Uint8List? bytes = await assets.readBinFile('ble_simple_peripheral.bin');
    // Uint8List? bytes = await assets.readBinFile('red_light_slow.bin');
    _ota(bytes);
  }

  ///方式3；定时器，模拟ota上传进程
  void startTimer(BuildContext context) {
    double _progress = 0;
    _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
      if (_progress < 1.0) {
        _progress += 0.01;
        classBKey.currentState?.setProgress(context, _progress);
      } else {
        timer.cancel(); // 取消定时器
        Navigator.pop(context, '');
      }
    });
  }

  ///ota方法
  void _ota(Uint8List? bytes) {
    _showDialog(context);
    Future.delayed(const Duration(milliseconds: 200), () {
      if (bytes != null) {
        OTA_FRI.binArray = bytes.toList();
        OTA_FRI.prepareOTA(
          callback: (service_uuid, characteristices, bytes, status) {
            switch (status) {
              case OTA_FRI_STATUS.read:
                BluetoothManager.instance.responseStream.listen((map) {
                  var data = map.values.first.values.first;
                  OTA_FRI.receiveData(data);
                });
              default:
                BluetoothManager.instance.write(characteristics_uuid: characteristices, data: bytes!);
                break;
            }
          },
          progress: (isWrite, progress) {
            int _progress = isWrite ? ((1 + progress) / 2 * 100).floor() : (progress / 2 * 100).floor();
            classBKey.currentState?.setProgress(context, _progress / 100);

            if (_progress >= 100) {
              Navigator.pop(context);
              EasyLoading.showSuccess('Update successfully');
            }
            String date = DateTime.now().toString();
            String action = isWrite ? '写入数据' : '擦除数据';
            String result = '${action}:${_progress}%';
            Provider.of<LogNotifier>(context, listen: false).newLog(result);
          },
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final bluetoothSate = Provider.of<DeviceConnectStateNotifier>(context);
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: ListView(
        children: [
          const SizedBox(height: 20),
          StreamBuilder(
              stream: bluetoothSate.connectedDevice?.connectionState,
              initialData: BluetoothConnectionState.disconnected,
              builder: (context, snapshot) {
                String connect = 'Unknown';
                bool enable = false;
                switch (snapshot.data) {
                  case BluetoothConnectionState.connected:
                    print('>Connected');
                    connect = 'Connected';
                    enable = true;
                  case BluetoothConnectionState.disconnected:
                    print('NOT Connect');
                    connect = 'NOT Connect';
                    enable = false;
                  case BluetoothConnectionState.connecting:
                    print('Connecting');
                    connect = 'Connecting';
                    enable = false;
                  case BluetoothConnectionState.disconnecting:
                    print('NOT Connect');
                    connect = 'NOT Connect';
                    enable = false;
                  default:
                }
                return Column(
                  children: [
                    _item(context, 'Connect State', connect),
                    _item(context, 'SSID:',
                        '${bluetoothSate.connectedDevice == null ? '' : bluetoothSate.connectedDevice?.platformName}'),
                    _item(context, 'Version:', ''),
                    _item2(context, enable),
                  ],
                );
              }),
        ],
      ),
    );
  }
}
